<?php

class CertificationPermissions
{
    private $permissions = 0;
    private $maxCertifications = 0;
    private $crud = array();

    const CREATE = 1;
    const READ = 2;
    const UPDATE = 4;
    const DESTROY = 8;
    const MODIFICAR_FIN = 16;
    const MODIFICAR_LIFE = 32;

    /**
     * MASCARAS
     */
    // Mascara con los permisos básicos
    const MASK_PERMISSIONS = 0x000000FF; // Parte donde se almacenan los permisos
    // Mascara para la parte que contiene el número máximo de certificaciones 
    // que se pueden iniciar en forma paralela por usuario.
    const MASK_MAX = 0x0000FF00;

    public function __construct($permissions) {
        $this->permissions = $permissions;
        $this->calculateBasicPermissions();
        $this->calculateMaxCertifications();
    }

    private function calculateBasicPermissions() {
        $basicPermissions = $this->permissions & self::MASK_PERMISSIONS;
        $this->crud = array(
            'create' => ($basicPermissions & self::CREATE) === self::CREATE,
            'read' => ($basicPermissions & self::READ) === self::READ,
            'update' => ($basicPermissions & self::UPDATE) === self::UPDATE,
            'destroy' => ($basicPermissions & self::DESTROY) === self::DESTROY,
            'end' => ($basicPermissions & self::MODIFICAR_FIN) === self::MODIFICAR_FIN,
            'life' => ($basicPermissions & self::MODIFICAR_LIFE) === self::MODIFICAR_LIFE,
        );
    }

    private function calculateMaxCertifications() {
        $this->maxCertifications = (($this->permissions & self::MASK_MAX) >> 8);
    }

    public function getMaxCertifications() {
        return $this->maxCertifications;
    }

    public function haveCreatePermission() {
        return $this->crud['create'];
    }

    public function haveReadPermission() {
        return $this->crud['read'];
    }

    public function haveUpdatePermission() {
        return $this->crud['update'];
    }

    public function haveDestroyPermission() {
        return $this->crud['destroy'];
    }
    
    public function haveModifyEnd() {
        return $this->crud['end'];
    }

    public function haveModifyLive() {
        return $this->crud['life'];
    }

    public function isReadOnly() {
        return $this->crud['create'] === false &&
                $this->crud['read'] === true &&
                $this->crud['update'] === false &&
                $this->crud['destroy'] === false;
    }

    public function toArray() {
        return array(
            'max' => $this->maxCertifications,
            'crud' => $this->crud,
        );
    }

    public static function toBin($create, $read, $update, $destroy, $end, $life) {
        $mf = $end === 'true' ? 1 : 0;
        $ml = $life === 'true' ? 1 : 0;
        $c = $create === 'true' ? 1 : 0;
        $r = $read === 'true' ? 1 : 0;
        $u = $update === 'true' ? 1 : 0;
        $d = $destroy === 'true' ? 1 : 0;
        return ($ml << 5) | ($mf << 4) | ($d << 3) | ($u << 2) | ($r << 1) | $c;
    }

}
